<?php
/**
 * Created by PhpStorm.
 * User: Aliaksei Lazerka
 * Date: 9/27/14
 * Time: 9:48 PM
 */

namespace test;

if (!defined('NYMPH_ROOT')) {
  define('NYMPH_ROOT', dirname("../../" . __FILE__));
  require(NYMPH_ROOT . '/local/loader/kernel/classes/URLClassLoader.php');
}

abstract class TestSuite
{

  private $hasAfter = false;
  private $hasBefore = false;
  private $defaultMethods = array('doAfter', 'doBefore', 'getAllTests', 'executeTests');
  private $testClasses = array();

  abstract function setTestClasses();

  function getAllTests($class)
  {
    $resultMethods = null;
    $methods = get_class_methods($class);
    $this->hasBefore = in_array('doBefore', $methods);
    $this->hasAfter = in_array('doAfter', $methods);
    foreach ($methods as $value) {
      if (!in_array($value, $this->defaultMethods)) {
        $resultMethods[] = $value;
      }
    }
    return $resultMethods;
  }

  function executeTests()
  {
    $this->setTestClasses();

    while ($testClass = array_pop($this->testClasses)) {
      $methods = self::getAllTests($testClass);

      $callBeforeAndAfter = is_subclass_of($testClass, ITestCaseImproved::class);
      if ($callBeforeAndAfter) {
        if ($this->hasBefore) {
          call_user_func($testClass . '::' . 'doBefore');
        }
      }

      foreach ($methods as $method) {
        $testSucceed = call_user_func($testClass . '::' . $method);
        if ($testSucceed) {
          TestActions::testSucceed($testClass . '::' . $method);
        } else {
          TestActions::testFailed($testClass . '::' . $method);
        }
      }

      if ($callBeforeAndAfter) {
        if ($this->hasAfter) {
          call_user_func($testClass . '::' . 'doAfter');
        }
      }
    }
  }

  function addTestClass($className)
  {
    array_push($this->testClasses, $className);
  }


}